#pragma once
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define ERROR_MESSAGE(NAME) \
    {                       \
        perror(NAME);       \
        exit(1);            \
    }
#define FIFO_PATH "./"
#define FIFO_NAME "fifo"
#define FIFO_PATHNAME "./fifo"
#define BUFF_SIZE (1024)

namespace My_Named_Pipe
{
    // server
    class Server
    {
    public:
        // 构造
        Server(const char* pathname)
            :_pathname(pathname)
        {
            // 建立fifo文件
            ::umask(0);
            int fiforet = ::mkfifo(_pathname, 0666);
            if (fiforet == -1)
            {
                ERROR_MESSAGE("mkfifo");
            }
            std::cout << "管道文件建立成功" << std::endl;
        }
        // 拷贝构造
        Server(const Server &cpy) = delete;
        // 赋值重载
        const Server operator=(const Server &cpy) = delete;
        // 析构
        ~Server()
        {
            // 删除文件
            unlink(_pathname);
            std::cout << "删除文件" << std::endl;
        }

        // open
        void _open()
        {
            // 打开文件
            _fd = ::open(_pathname, O_RDONLY);
            if (_fd == -1)
            {
                ERROR_MESSAGE("open");
            }
            std::cout << "读打开文件" << std::endl;
        }

        // read
        void _read()
        {
            std::cout << "开始读取->" << std::endl;
            // 读文件
            while (1)
            {
                char buffer[BUFF_SIZE] = {0};
                ssize_t readret = ::read(_fd, buffer, sizeof(buffer));
                std::cout << buffer << std::endl;
                if (strcmp(buffer, "close") == 0)
                {
                    break;
                }
            }
        }

        // close
        void _close()
        {
            // 关闭文件
            ::close(_fd);
            std::cout << "关闭文件" << std::endl;
        }

    private:
        int _fd;
        const char*  _pathname;
    };

    // client
    class Client
    {
    public:
        // 构造
        Client(const char* pathname)
            :_pathname(pathname)
        { }
        // 拷贝构造
        Client(const Client &cpy) = delete;
        // 赋值重载
        const Client operator=(const Client &cpy) = delete;
        // 析构
        ~Client() = default;

        // open
        void _open()
        {
            // 打开文件
            _fd = ::open(_pathname, O_WRONLY);
            if (_fd == -1)
            {
                ERROR_MESSAGE("open");
            }
            std::cout << "写打开文件" << std::endl;
        }
        // wriht
        void _write()
        {
            std::cout << "开始写入->" << std::endl;
            // 写文件
            while (1)
            {
                char buffer[BUFF_SIZE] = {0};
                std::cin >> buffer;
                ssize_t writeret = ::write(_fd, buffer, sizeof(buffer));
                // std::cout<< buffer << std::endl;
                if (strcmp(buffer, "close") == 0)
                {
                    break;
                }
            }
        }

        // close
        void _close()
        {
            // 关闭文件
            ::close(_fd);
            std::cout << "关闭文件" << std::endl;
        }

    private:
        int _fd;
        const char*  _pathname;
    };
}